package yartiss.gui.view;

import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Image;
import java.awt.LayoutManager;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.AdjustmentEvent;
import java.awt.event.AdjustmentListener;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.image.BufferedImage;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.File;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.imageio.ImageIO;
import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.DefaultCellEditor;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JFileChooser;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSpinner;
import javax.swing.JSplitPane;
import javax.swing.JTabbedPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.KeyStroke;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import javax.swing.filechooser.FileFilter;

import net.miginfocom.swing.MigLayout;
import yartiss.framework.view.AbstractView;
import yartiss.framework.viewmodel.AbstractViewModel;
import yartiss.gui.graphics.JEnergyCurve;
import yartiss.gui.graphics.JProcessorDiagram;
import yartiss.gui.graphics.JTaskDiagram;
import yartiss.service.model.IEventsModel;
import yartiss.service.model.TasksTableModel;

@SuppressWarnings("serial")
public class TimelineView extends AbstractView{

	private IEventsModel eventsModel;
	public final JTaskDiagram taskDiag = new JTaskDiagram(null);
	public final JProcessorDiagram procDiag = new JProcessorDiagram(null);
	public final JProcessorDiagram procDiag2 = new JProcessorDiagram(null);
	public final JEnergyCurve energyCurve = new JEnergyCurve(null);
	public JButton startSimulation;
	public JButton load;
	public JButton addTask;
	public JButton removeTask;
	public JButton generate;
	public JButton screenShot;

	public JCheckBox showEnergyCurve;
	public JCheckBox showSlackEnergyCurve;
	public JCheckBox showSlackTimeCurve;
	public JCheckBox isGlobalConsupltionCheckBox;
	public JCheckBox isEnergyAware;

	public JSpinner alternateX;
	public JSpinner alternateY;
	public JSpinner xScale;
	public JSpinner yScale;

	public JComboBox<String> availibalePolicies;
	public JComboBox<String> availibaleConsumptionProfiles;

	public JTextField durationField;
	public JTextField endField;
	public JTextField stateField;
	public JTextField averageIdlePeriodField;
	public JTextField averageBusyPeriodField;
	public JTextField timeAtEmaxField;
	public JTextField timeAtEminField;
	public JTextField E0Field;
	public JTextField EminField;
	public JTextField PrField;
	public JTextField EmaxField;
	public JTextField busyPeriodField;
	public JTextField hyperPeriodField;
	public JTextField utilizationField;
	public JTextField energyUtilizationField;
	public JTextField countField;
	public JTextField policyParametersField;
	public JTextField nbProcField;
	public JTextField selectedPolicyNameField = new JTextField();
	public JTextField selectedConsumptionProfileField = new JTextField();

	public AbstractViewModel viewModel;
	public TasksTableModel tasksModel;
	public JTable tasksTable;	
	public ActionListener generateCommand = null;
	public ActionListener startSimulationCommand = null;
	public ActionListener loadCommand = null;
	public ActionListener saveCommand = null;


	public TimelineView(){
		setResizeWeight(1.0);
		setOneTouchExpandable(true);
		setLeftComponent(buildLeftComponent());
		setRightComponent(buildRightComponent());
		registerGUIListerners();
		initializeGUI();
	}

	@Override
	public AbstractViewModel getDataContext() {
		return viewModel;
	}


	@Override
	public void setDataContext(AbstractViewModel viewModel) {
		unSuscribeListeners();
		this.viewModel = viewModel;
		suscribeListeners();
		fireViewModelChanged(viewModel);
	}

	private void fireViewModelChanged(AbstractViewModel vm){
		IEventsModel model = vm.getProperty("EventsModel");
		taskDiag.setEventsModel(model);
		procDiag.setEventsModel(model);
		procDiag2.setEventsModel(model);
		energyCurve.setEventsModel(model);
		for (String propName : propertiesNames) {
			setProperty(propName);
		}
		setProperty("TasksModel");
		setProperty("EventsModel");
		setProperty("AvailablePolicies");
		setProperty("AvailibaleConsumptionProfiles");
		setProperty("GenerateCommand");
		setProperty("StartSimulationCommand");
		setProperty("IsContentChanged");
		setProperty("IsGlobalConsumption");
		setProperty("isEnergyAware");
		setProperty("SelectedPolicyName");
		setProperty("SelectedConsumptionProfile");
		setProperty("LoadCommand");
		setProperty("SaveCommand");
	}

	private void setProperty(String propName){
		Object value = viewModel.getProperty(propName);
		if("EventsModel".equals(propName)){
			eventsModel = viewModel.getProperty(propName);
			taskDiag.setEventsModel(eventsModel);
			procDiag.setEventsModel(eventsModel);
			procDiag2.setEventsModel(eventsModel);
			energyCurve.setEventsModel(eventsModel);
		}
		else if("SelectedPolicyName".equals(propName)){ 
			selectedPolicyNameField.setText(value.toString());
			availibalePolicies.setSelectedItem(value+"");
		}
		else if("SelectedConsumptionProfile".equals(propName)){ 
			selectedConsumptionProfileField.setText(value.toString());
			availibaleConsumptionProfiles.setSelectedItem(value+"");
		}
		else if("AvailablePolicies".equals(propName)){ 
			String [] policies = viewModel.getProperty(propName);
			availibalePolicies.setModel(new DefaultComboBoxModel<String>(policies));
			selectedPolicyNameField.setText(policies[0]);
		}
		else if("AvailibaleConsumptionProfiles".equals(propName)){ 
			String [] profiles = viewModel.getProperty(propName);
			availibaleConsumptionProfiles.setModel(new DefaultComboBoxModel<String>(profiles));
			selectedConsumptionProfileField.setText(profiles[0]);
		}
		else if("TasksModel".equals(propName)){ 
			tasksModel = viewModel.getProperty(propName);
			tasksTable.setModel(tasksModel);
			taskTypeEditor.setModel(new DefaultComboBoxModel<String>(tasksModel.getSchedulablesTypes()));
			consTypeEditor.setModel(new DefaultComboBoxModel<String>(tasksModel.getConsumptionFrofiles()));

			tasksTable.getColumnModel().getColumn(0).setCellEditor(new DefaultCellEditor(taskTypeEditor));
			if(tasksTable.getColumnModel().getColumnCount() > 7)
				tasksTable.getColumnModel().getColumn(7).setCellEditor(new DefaultCellEditor(consTypeEditor));

			tasksModel.addTableModelListener(new TableModelListener() {
				@Override public void tableChanged(TableModelEvent e) {
					if(tasksModel.getRowCount() <= 0)
						removeTask.setEnabled(false);
					else 
						removeTask.setEnabled(true);
				}
			});
		}
		else if("LoadCommand".equals(propName)){  
			load.removeActionListener(loadCommand);
			loadCommand = viewModel.getProperty(propName);
			load.addActionListener(loadCommand);
		}
		else if("SaveCommand".equals(propName)){  
			save.removeActionListener(saveCommand);
			saveCommand = viewModel.getProperty(propName);
			save.addActionListener(saveCommand);
		}
		else if("GenerateCommand".equals(propName)){  
			generate.removeActionListener(generateCommand);
			generateCommand = viewModel.getProperty(propName);
			generate.addActionListener(generateCommand);
		}
		else if("StartSimulationCommand".equals(propName)){ 
			startSimulation.removeActionListener(startSimulationCommand);
			startSimulationCommand = viewModel.getProperty(propName);
			startSimulation.addActionListener(startSimulationCommand);
		}
		else if("IsContentChanged".equals(propName)){
			Boolean enabled = viewModel.getProperty(propName);
			startSimulation.setEnabled(enabled);
		}
		else if("IsGlobalConsumption".equals(propName)){
			boolean selected = viewModel.getProperty(propName);
			isGlobalConsupltionCheckBox.setSelected(selected);
			availibaleConsumptionProfiles.setEnabled(selected);
			if(isEnergyAware.isSelected() && tasksTable.getColumnModel().getColumnCount() > 7)
				tasksTable.getColumnModel().getColumn(7).setCellEditor(new DefaultCellEditor(consTypeEditor));
		}
		else if("isEnergyAware".equals(propName)){
			boolean energyWare = viewModel.getProperty(propName);
			isEnergyAware.setSelected(energyWare);
			if(isEnergyAware.isSelected()){
				energyCurveScrollPane.setViewportView(energyCurve);
				energyCurveScrollPane.setBorder(BorderFactory.createTitledBorder("Energy evolution"));

			}
			else {
				energyCurveScrollPane.setViewportView(procDiag2);
				energyCurveScrollPane.setBorder(BorderFactory.createTitledBorder("Processors chronogram"));
			}
			energyProfilePane.setVisible(isEnergyAware.isSelected());
			energyUtilizationField.setVisible(isEnergyAware.isSelected());
			energyULabel.setVisible(isEnergyAware.isSelected());
			if(isEnergyAware.isSelected() && tasksTable.getColumnModel().getColumnCount() > 7)
				tasksTable.getColumnModel().getColumn(7).setCellEditor(new DefaultCellEditor(consTypeEditor));
		}
		else if("emax".equals(propName)){
			int val = viewModel.getProperty(propName);
			energyCurve.setMaxLevel(val);
			setProperty(propName, value);
		}
		else if("emin".equals(propName)){
			int val1 = viewModel.getProperty(propName);
			energyCurve.setMinLevel(val1);
			setProperty(propName, value);
		}
		else {
			setProperty(propName, value);
		}
	}

	private PropertyChangeListener listener = new PropertyChangeListener() {
		@Override  public void propertyChange(PropertyChangeEvent evt) {
			setProperty(evt.getPropertyName());
		}
	};
	private JButton save;
	private JComboBox<String> taskTypeEditor;
	private JComboBox<String> consTypeEditor;
	private JScrollPane energyCurveScrollPane;
	private JPanel energyProfilePane;
	private JLabel energyULabel;

	private void suscribeListeners() {
		if(viewModel != null)
			viewModel.registerPropertyChangeListerner(listener);
	}

	private void unSuscribeListeners() {
		if(viewModel != null)
			viewModel.unregisterPropertyChangeListener(listener);
	}

	private JComponent buildLeftComponent(){

		taskDiag.setXUnit(10);
		procDiag.setXUnit(10);
		procDiag2.setXUnit(10);

		energyCurve.setSlackEnergyCurveEnabled(true);
		energyCurve.setSlackTimeCurveEnabled(true);

		final JScrollPane taskDiagScrollPane = new JScrollPane(taskDiag);
		taskDiagScrollPane.setBorder(BorderFactory.createTitledBorder("Tasks chronogram"));
		taskDiagScrollPane.setAutoscrolls(true);

		final JScrollPane procDiagScrollPane = new JScrollPane(procDiag);
		procDiagScrollPane.setBorder(BorderFactory.createTitledBorder("Processors chronogram"));
		procDiagScrollPane.setAutoscrolls(true);

		energyCurveScrollPane = new JScrollPane(energyCurve);
		energyCurveScrollPane.setBorder(BorderFactory.createTitledBorder("Energy evolution"));
		energyCurveScrollPane.setAutoscrolls(true);

		JTabbedPane southPanel = new  JTabbedPane();
		southPanel.addTab("Tasks", taskDiagScrollPane);
		southPanel.addTab("Procesors", procDiagScrollPane);

		JSplitPane panel = new JSplitPane(JSplitPane.VERTICAL_SPLIT);
		panel.setTopComponent(energyCurveScrollPane);
		panel.setBottomComponent(southPanel);
		panel.setResizeWeight(0.5);
		panel.setOneTouchExpandable(true);
		panel.setOpaque(true);

		taskDiagScrollPane.getHorizontalScrollBar().addAdjustmentListener(new AdjustmentListener() {
			@Override
			public void adjustmentValueChanged(AdjustmentEvent e) {
				Point vp1 = taskDiagScrollPane.getViewport().getViewPosition();
				Point vp2 = energyCurveScrollPane.getViewport().getViewPosition();
				vp2.x = vp1.x;
				energyCurveScrollPane.getViewport().setViewPosition(vp2);
				procDiagScrollPane.getViewport().setViewPosition(vp2);
			}
		});

		energyCurveScrollPane.getHorizontalScrollBar().addAdjustmentListener(new AdjustmentListener() {
			@Override
			public void adjustmentValueChanged(AdjustmentEvent e) {
				Point vp1 = energyCurveScrollPane.getViewport().getViewPosition();
				Point vp2 = energyCurveScrollPane.getViewport().getViewPosition();
				vp2.x = vp1.x;
				taskDiagScrollPane.getViewport().setViewPosition(vp2);
				procDiagScrollPane.getViewport().setViewPosition(vp2);
			}
		});

		procDiagScrollPane.getHorizontalScrollBar().addAdjustmentListener(new AdjustmentListener() {
			@Override
			public void adjustmentValueChanged(AdjustmentEvent e) {
				Point vp1 = procDiagScrollPane.getViewport().getViewPosition();
				Point vp2 = procDiagScrollPane.getViewport().getViewPosition();
				vp2.x = vp1.x;
				energyCurveScrollPane.getViewport().setViewPosition(vp2);
				taskDiagScrollPane.getViewport().setViewPosition(vp2);
			}
		});
		return panel;
	}

	private JComponent buildRightComponent(){
		JPanel simulationPane = new JPanel();
		BoxLayout b = new BoxLayout(simulationPane, BoxLayout.Y_AXIS);
		simulationPane.setLayout(b);
		simulationPane.setBorder(BorderFactory.createTitledBorder("Simulation"));

		startSimulation = new JButton("Go");
		load = new JButton("load");
		save = new JButton("Save");

		screenShot = new JButton("Shot");
		durationField = new JTextField(15); 

		showEnergyCurve = new JCheckBox("Energy level");
		showSlackEnergyCurve = new JCheckBox("Slack energy");
		showSlackTimeCurve = new JCheckBox("Slack time");

		endField = new JTextField(15); endField.setEnabled(false);
		stateField = new JTextField(15);	stateField.setEnabled(false);
		averageIdlePeriodField = new JTextField(15);		averageIdlePeriodField.setEnabled(false);
		averageBusyPeriodField = new JTextField(15);		averageBusyPeriodField.setEnabled(false);
		timeAtEmaxField = new JTextField(15);	timeAtEmaxField.setEnabled(false);
		timeAtEminField = new JTextField(15);	timeAtEminField.setEnabled(false);
		alternateX = new JSpinner();
		alternateY = new JSpinner();
		xScale = new JSpinner();
		yScale = new JSpinner();

		alternateX.setMinimumSize(new Dimension(50, 20));
		alternateY.setMinimumSize(new Dimension(50, 20));
		xScale.setMinimumSize(new Dimension(50, 20));
		yScale.setMinimumSize(new Dimension(50, 20));
		alternateX.setEditor(new JSpinner.NumberEditor(alternateX));
		alternateY.setEditor(new JSpinner.NumberEditor(alternateY));
		xScale.setEditor(new JSpinner.NumberEditor(xScale));
		yScale.setEditor(new JSpinner.NumberEditor(yScale));

		JPanel displaySettings = new JPanel();
		BoxLayout layoutt = new BoxLayout(displaySettings, BoxLayout.Y_AXIS);
		displaySettings.setLayout(layoutt);
		JPanel p = new JPanel(new MigLayout());
		p.add(startSimulation, "gap para");
		p.add(load, "gap para");
		p.add(save, "gap para");
		p.add(new JLabel("Duratiobn"), "gap para");p.add(durationField );

		//p.add(screenShot, "gap para");
		simulationPane.add(p);

		p = new JPanel(new MigLayout());
		p.add(showEnergyCurve, "gap para");
		p.add(showSlackEnergyCurve, "gap para");
		p.add(showSlackTimeCurve    );
		displaySettings.add(p,"growx, wrap, gaptop 10");

		p = new JPanel(new MigLayout());
		p.add(new JLabel("X alternate"), "gap para");p.add(alternateX, "gap para");
		p.add(new JLabel("Y alternate"), "gap para");p.add(alternateY    , "gap para");
		p.add(new JLabel()    , "span, growx, wrap para");
		p.add(new JLabel("Scale X"), "gap para");p.add(xScale, "gap para");
		p.add(new JLabel("Scale Y"), "gap para");p.add(yScale, "gap para");
		displaySettings.setBorder(BorderFactory.createTitledBorder("Display setting"));
		displaySettings.add(p);
		simulationPane.add(displaySettings,"growx, wrap, gaptop 10");

		p = new JPanel(new MigLayout());
		p.add(new JLabel("State"), "gap para");p.add(stateField    , "gap para");
		p.add(new JLabel("End"), "gap para");p.add(endField    , "span, growx, wrap para");
		p.add(new JLabel("IP"), "gap para");p.add(averageIdlePeriodField    ,"gap para");
		p.add(new JLabel("BP"), "gap para");p.add(averageBusyPeriodField    , "span, growx, wrap para");
		p.add(new JLabel("Tmax"), "gap para");p.add(timeAtEmaxField    , "gap para");
		p.add(new JLabel("Tmin"), "gap para");p.add(timeAtEminField );
		p.setBorder(BorderFactory.createTitledBorder("Results"));
		simulationPane.add(p,"growx, wrap, gaptop 10");

		JPanel schedulingPolicyPane = new JPanel(new MigLayout());
		schedulingPolicyPane.setBorder(BorderFactory.createTitledBorder("Scheduling policy"));

		policyParametersField = new JTextField(15);
		nbProcField = new JTextField(15);
		availibalePolicies = new JComboBox<String>();
		isEnergyAware = new JCheckBox("is energy aware");

		schedulingPolicyPane.add(new JLabel("Policy"), "gap 10");	schedulingPolicyPane.add(availibalePolicies    , "gap 10");
		schedulingPolicyPane.add(new JLabel("Parameters"), "gap 10");schedulingPolicyPane.add(policyParametersField    ,"span, growx, wrap para" );
		schedulingPolicyPane.add(new JLabel("Proc count"), "gap 10");	schedulingPolicyPane.add(nbProcField    ,"gap 10");
		schedulingPolicyPane.add(isEnergyAware, "gap 10");	

		energyProfilePane = new JPanel(new MigLayout());
		energyProfilePane.setBorder(BorderFactory.createTitledBorder("Energy profile"));

		E0Field 	= new JTextField(15);
		EminField = new JTextField(15);
		PrField 	= new JTextField(15);
		EmaxField = new JTextField(15);
		availibaleConsumptionProfiles = new JComboBox<String>();
		availibaleConsumptionProfiles.setMaximumSize(new Dimension(110,50));
		isGlobalConsupltionCheckBox = new JCheckBox("Global"); 
		energyProfilePane.add(new JLabel("E0"), "gap 10");	energyProfilePane.add(E0Field    , "gap 10");
		energyProfilePane.add(new JLabel("Pr"), "gap 10");	energyProfilePane.add(PrField    , "span, growx, wrap para");
		energyProfilePane.add(new JLabel("Emax"), "gap 10");energyProfilePane.add(EmaxField    , "gap 10");
		energyProfilePane.add(new JLabel("Emin"), "gap 10");energyProfilePane.add(EminField    , "span, growx, wrap para");
		energyProfilePane.add(new JLabel("Consuption"), "gap 10");energyProfilePane.add(availibaleConsumptionProfiles    , "gap 10");
		energyProfilePane.add(isGlobalConsupltionCheckBox);		

		JPanel systemPane = new JPanel(new MigLayout());
		systemPane.setBorder(BorderFactory.createTitledBorder("System"));

		addTask 	= new JButton("add");
		removeTask 	= new JButton("remove");
		generate = new JButton("Generate");

		busyPeriodField  = new JTextField(15);
		hyperPeriodField = new JTextField(15);
		utilizationField = new JTextField(15);
		energyUtilizationField = new JTextField(15);
		countField = new JTextField(15);

		systemPane.add(addTask    );
		systemPane.add(removeTask   );
		systemPane.add(generate    , "span, growx, wrap para");


		tasksTable = new JTable();
		taskTypeEditor= new JComboBox<String>();
		consTypeEditor= new JComboBox<String>();

		JScrollPane sp = new JScrollPane(tasksTable);
		sp.setMinimumSize(new Dimension(50,70));
		systemPane.add(sp,"span, growx, wrap para");

		systemPane.add(new JLabel("Count"), "gap 10");systemPane.add(countField    , "span, growx, wrap para");
		systemPane.add(new JLabel("Time U"), "gap 10");systemPane.add(utilizationField    , "gap para");	
		energyULabel = new JLabel("Energy U");
		systemPane.add(energyULabel, "gap 10");systemPane.add(energyUtilizationField    , "span, growx, wrap para");	
		systemPane.add(new JLabel("Busy period"), "gap 10");systemPane.add(busyPeriodField    , "gap para");	
		systemPane.add(new JLabel("hyper period"), "gap 10");systemPane.add(hyperPeriodField );	

		JPanel rightPane = new JPanel();
		BoxLayout layout = new BoxLayout(rightPane, BoxLayout.Y_AXIS);
		rightPane.setLayout(layout);
		rightPane.add(simulationPane);
		rightPane.add(schedulingPolicyPane);
		rightPane.add(energyProfilePane);
		rightPane.add(systemPane);

		JPanel pp = new JPanel(new LayoutManager() {
			int width=400;
			//int height=800;
			@Override public void removeLayoutComponent(Component comp) {}

			@Override public Dimension preferredLayoutSize(Container parent) {
				return new Dimension(width,parent.getHeight());
			}

			@Override public Dimension minimumLayoutSize(Container parent) {
				return new Dimension(width,parent.getHeight());
			}

			@Override public void layoutContainer(Container parent) {
				for (Component comp : parent.getComponents()) {
					comp.setSize(width, parent.getHeight());
				}
			}
			@Override public void addLayoutComponent(String name, Component comp) {}
		});

		pp.add(rightPane);

		JScrollPane Scroll = new JScrollPane(pp);
		Scroll.setMinimumSize(new Dimension(410,0));
		Scroll.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
		return Scroll;
	}

	private void initializeGUI(){
		taskDiag.setOpaque(true);
		procDiag.setOpaque(true);
		procDiag2.setOpaque(true);
		energyCurve.setOpaque(true);

		int xscale = 30, yscale = 5, yunit=30, xalternate = 2, yalternate=10;
		xScale.setValue(xscale);
		taskDiag.setXUnit(xscale);
		energyCurve.setXUnit(xscale);

		yScale.setValue(yscale);
		taskDiag.setYUnit(yunit);

		alternateX.setValue(xalternate);
		taskDiag.setxAlternate(xalternate);
		energyCurve.setXAlternate(xalternate);

		alternateY.setValue(yalternate);
		energyCurve.setyAlternate(yalternate);
		energyCurve.setSlackTimeCurveEnabled(false);
		energyCurve.setSlackEnergyCurveEnabled(false);
		energyCurve.setEnergyLevelEnabled(true);
		showEnergyCurve.setSelected(true);
	}

	private void registerGUIListerners(){
		xScale.addChangeListener(new ChangeListener() {
			@Override public void stateChanged(ChangeEvent e) {
				int value = Integer.parseInt(xScale.getValue().toString());
				taskDiag.setXUnit(value);
				procDiag.setXUnit(value);
				procDiag2.setXUnit(value);
				energyCurve.setXUnit(value);
			}
		});
		yScale.addChangeListener(new ChangeListener() {
			@Override public void stateChanged(ChangeEvent e) {
				int value = Integer.parseInt(yScale.getValue().toString());
				energyCurve.setYUnit(value);
			}
		});
		alternateX.addChangeListener(new ChangeListener() {
			@Override public void stateChanged(ChangeEvent e) {
				int value = Integer.parseInt(alternateX.getValue().toString());
				taskDiag.setxAlternate(value);
				procDiag.setxAlternate(value);
				procDiag2.setxAlternate(value);
				energyCurve.setXAlternate(value);
			}
		});
		alternateY.addChangeListener(new ChangeListener() {
			@Override public void stateChanged(ChangeEvent e) {
				int value = Integer.parseInt(alternateY.getValue().toString());
				energyCurve.setyAlternate(value);
			}
		});
		showEnergyCurve.addActionListener(new ActionListener() {
			@Override public void actionPerformed(ActionEvent e) {
				energyCurve.setEnergyLevelEnabled(showEnergyCurve.isSelected());
			}
		});
		showSlackTimeCurve.addActionListener(new ActionListener() {
			@Override public void actionPerformed(ActionEvent e) {
				energyCurve.setSlackTimeCurveEnabled(showSlackTimeCurve.isSelected());
			}
		});
		showSlackEnergyCurve.addActionListener(new ActionListener() {
			@Override public void actionPerformed(ActionEvent e) {
				energyCurve.setSlackEnergyCurveEnabled(showSlackEnergyCurve.isSelected());
			}
		});
		addTask.addActionListener(new ActionListener() {
			@Override public void actionPerformed(ActionEvent e) {
				tasksModel.addRow();
			}
		});
		removeTask.addActionListener(new ActionListener() {
			@Override public void actionPerformed(ActionEvent e) {
				int selectedRow = tasksTable.getSelectedRow();
				if(selectedRow >= 0)
					tasksModel.removeRow(selectedRow);
			}
		});
		isGlobalConsupltionCheckBox.addActionListener(new ActionListener() {
			@Override public void actionPerformed(ActionEvent e) {
				viewModel.setProperty("IsGlobalConsumption", isGlobalConsupltionCheckBox.isSelected());
				startSimulation.setEnabled(true);
				availibaleConsumptionProfiles.setEnabled(isGlobalConsupltionCheckBox.isSelected());
				if(isEnergyAware.isSelected() && tasksTable.getColumnModel().getColumnCount() > 7)
					tasksTable.getColumnModel().getColumn(7).setCellEditor(new DefaultCellEditor(consTypeEditor));
			}
		});

		isEnergyAware.addActionListener(new ActionListener() {
			@Override public void actionPerformed(ActionEvent e) {
				viewModel.setProperty("IsEnergyAware", isEnergyAware.isSelected());
				startSimulation.setEnabled(true);
				if(isEnergyAware.isSelected()){
					energyCurveScrollPane.setViewportView(energyCurve);
					energyCurveScrollPane.setBorder(BorderFactory.createTitledBorder("Energy evolution"));

				}
				else {
					energyCurveScrollPane.setViewportView(procDiag2);
					energyCurveScrollPane.setBorder(BorderFactory.createTitledBorder("Processors chronogram"));
				}
				energyProfilePane.setVisible(isEnergyAware.isSelected());
				energyUtilizationField.setVisible(isEnergyAware.isSelected());
				energyULabel.setVisible(isEnergyAware.isSelected());
				if(isEnergyAware.isSelected() && tasksTable.getColumnModel().getColumnCount() > 7)
					tasksTable.getColumnModel().getColumn(7).setCellEditor(new DefaultCellEditor(consTypeEditor));
			}
		});

		ActionListener listener2 = new ActionListener() {
			@Override public void actionPerformed(ActionEvent e) {
				energyCurve.setMaxLevel(Integer.parseInt(EmaxField.getText()));
				energyCurve.setMinLevel(Integer.parseInt(EminField.getText()));
			}
		};
		FocusListener focusListener = new FocusListener() {
			@Override
			public void focusLost(FocusEvent e) {
				energyCurve.setMaxLevel(Integer.parseInt(EmaxField.getText()));
				energyCurve.setMinLevel(Integer.parseInt(EminField.getText()));
			}
			@Override
			public void focusGained(FocusEvent e) {}
		};
		EmaxField.addActionListener( listener2);
		EminField.addActionListener( listener2);
		EmaxField.addFocusListener( focusListener);
		EminField.addFocusListener( focusListener);

		availibalePolicies.addActionListener( new MyActionListerner(null, "SelectedPolicyName"));
		availibaleConsumptionProfiles.addActionListener(new MyActionListerner(null, "SelectedConsumptionProfile"));
		addListeners(policyParametersField,"PolicyParameters");
		addListeners(durationField,"Duration");
		addListeners(E0Field,"E0");
		addListeners(EminField,"Emin");
		addListeners(PrField,"Pr");
		addListeners(EmaxField,"Emax");
		addListeners(busyPeriodField,"BusyPeriod");
		addListeners(hyperPeriodField,"HyperPeriod");
		addListeners(utilizationField,"Utilization");
		addListeners(energyUtilizationField,"EnergyUtilization");
		addListeners(countField,"Count");
		addListeners(nbProcField,"NbProc");

		registerKeyboardAction(
				new ActionListener() {@Override	public void actionPerformed(ActionEvent arg0) {saveCommand.actionPerformed(arg0);}},
				KeyStroke.getKeyStroke(KeyEvent.VK_S, InputEvent.CTRL_MASK),JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);

		registerKeyboardAction(
				new ActionListener() {@Override	public void actionPerformed(ActionEvent arg0) {loadCommand.actionPerformed(arg0);}},
				KeyStroke.getKeyStroke(KeyEvent.VK_O, InputEvent.CTRL_MASK),JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);

		final ActionListener screenShotCommand = new ActionListener() {
			@Override public void actionPerformed(ActionEvent e) {
				Image diag1 = taskDiag.getScreenShot();
				Image diag2 = procDiag.getScreenShot();
				Image curve = energyCurve.getScreenShot();
				BufferedImage img = new BufferedImage(diag1.getWidth(null), diag1.getHeight(null)+diag2.getHeight(null)+curve.getHeight(null),  BufferedImage.TYPE_INT_ARGB);
				img.getGraphics().drawImage(curve, 0, 0,curve.getWidth(null), curve.getHeight(null), null);
				img.getGraphics().drawImage(diag1, 0, curve.getHeight(null), diag1.getWidth(null), diag1.getHeight(null), null);
				img.getGraphics().drawImage(diag2, 0, diag1.getHeight(null)+curve.getHeight(null), diag2.getWidth(null), diag2.getHeight(null), null);

				JFileChooser fileChooser = new JFileChooser();
				fileChooser.setFileFilter(new FileFilter() {
					@Override
					public String getDescription() {
						return "png";
					}

					@Override
					public boolean accept(File f) {
						return true;
					}
				});
				int result = fileChooser.showSaveDialog(TimelineView.this);
				if (result == JFileChooser.APPROVE_OPTION) {
					File file = fileChooser.getSelectedFile();
					try {
						File outputfile = new File(file.getPath()+".png");
						ImageIO.write(img, "png", outputfile);
						System.out.println("Screen Shot generated");
					} catch (Exception e1) {
						e1.printStackTrace();
					}
				}
			}
		};
		screenShot.addActionListener(screenShotCommand);
		registerKeyboardAction(screenShotCommand,KeyStroke.getKeyStroke(KeyEvent.VK_P, InputEvent.CTRL_MASK),JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
	}

	public class MyActionListerner implements ActionListener, FocusListener, KeyListener{

		private final String propName;
		String oldValue;
		private final JTextField source;
		private boolean valide;
		public MyActionListerner(JTextField source, String propName){
			this.source = source;
			this.propName = propName;
		}
		@Override public void actionPerformed(ActionEvent e) {doIt(e.getSource());}
		@Override public void focusGained(FocusEvent e) {oldValue = source != null ? source.getText() : "";}
		@Override public void focusLost(FocusEvent e) {doIt(e.getSource());}
		private void doIt(Object source){
			Object value = null;
			if(source == availibalePolicies){
				setProperty(propName,availibalePolicies.getSelectedItem().toString());
				value = getProperty(propName);
				fireGuiPropertyChanged(propName, value, value);
			}
			if(source == availibaleConsumptionProfiles){
				setProperty(propName,availibaleConsumptionProfiles.getSelectedItem().toString());
				value = getProperty(propName);
				fireGuiPropertyChanged(propName, value, value);
			}
			if(this.source != null && !valide){
				this.source.setText(oldValue);
				this.source.setForeground(Color.BLACK);
			}
			value = getProperty(propName);
			fireGuiPropertyChanged(propName, value, value);
		}
		@Override
		public void keyTyped(KeyEvent e) {
			String input = source.getText();
			Pattern p = Pattern.compile("[A-Z,a-z,&%$#@!()*^]");
			Matcher m = p.matcher(input);
			if (m.find()){
				source.setForeground(Color.RED);
				valide = false;
			}
			else {
				source.setForeground(Color.black);
				valide = true;
			}
		}
		@Override public void keyPressed(KeyEvent e) {}
		@Override public void keyReleased(KeyEvent e) {}
	}

	private void addListeners(JTextField f, String prop){
		MyActionListerner l = new MyActionListerner(f, prop);
		f.addActionListener(l);
		f.addFocusListener(l);
		f.addKeyListener(l);
	}

}
